#ifndef MSPROTOCOL_H
#define MSPROTOCOL_H
#ifdef __cplusplus
   extern "C"{
#endif
/******************************************************************************
 ******************************************************************************
  File Name     : url.h
  Version       : Initial Draft
  Author        : su<sugao_cn@163.com>
  Created       : 2015/4/14
  Last Modified :
  Description   : url file
  Function List :
  History       :
  1.Date        : 2015/4/14
    Author      : su<sugao_cn@163.com>
    Modification: Created file

******************************************************************************/
#if defined(OS_ANDROID)||defined(OS_LINUX_SOC)
#include <netinet/in.h>
#elif defined(OS_WIN32)
#include <winsock2.h>
#endif
#include <libmscommon/msthread.h>
#include <libmscommon/mstypes.h>
#include <libmscommon/msfifo.h>
#include <libmscommon/msdenc.h>
#include <libmslog/mstype.h>

/*******************************************
HTTP和RTSP版本信息
*******************************************/
#define MSPTC_VERSION_HTTP_10		"HTTP/1.0"
#define MSPTC_VERSION_HTTP_11		"HTTP/1.1"
#define MSPTC_VERSION_RTSP_10		"RTSP/1.0"
#define MSPTC_VERSION_RTSP_11		"RTSP/1.1"

/*******************************************
FLAG选项
*******************************************/
#define FLAG_READ				(0<<0)
#define FLAG_WRITE				(1<<0)			
#define FLAG_READ_WRITE			(1<<1)
#define FLAG_FILE_APPEND		(1<<2)
#define FLAG_FILE_EMPTY			(1<<3)
#define FLAG_FILE_NOCREATE		(1<<4)
#define FLAG_USE_THREAD_FIFO	(1<<5)
#define FLAG_DATA_NOCOPY		(1<<6)
#define FLAG_BROADCAST			(1<<7)
#define FLAG_NOCHECKEXSIT		(1<<8)	

/*******************************************
文件检测选项：存在、可读、可写
*******************************************/
#define MSFILE_CHECK_EXSIT		(1<<0)	
#define MSFILE_CHECK_READ		(1<<1)
#define MSFILE_CHECK_WRITE		(1<<2)

/*******************************************
无效FD
*******************************************/
#define UNVALID_FD		-1 

/*******************************************
端口
*****************************************/
#define ms_unvalidport			(-1)
#define ms_defaultport_rtsp		554
#define ms_defaultport_http		80
#define ms_defaultport_rtmp		1935

/*******************************************
RTP信息
*****************************************/
#define RTP_IFRAME_MAGIC_NUM       0x24
#define RTP_IFRAME_LEN  	4
#define RTP_HEASER_LEN		12

/*******************************************
环境变量
*****************************************/
#define msenv_ptl_rtsptransport		"msenv_ptl_rtsptransport"
#define msenv_ptl_rtpsequencenum	"msenv_ptl_rtpsequencenum"
#define msenv_ptl_useragent			"msenv_ptl_useragent"
#define msenv_ptl_hasipv6			"msenv_ptl_hasipv6"

/*******************************************
可修改配置信息
*******************************************/
#define mscfg_maxnum_port		65535
//作为RTSP服务端，分配给客户端的RTP端口范围[42000,mscfg_maxnum_port]
#define mscfg_rtspserver_baseport		42000
#define mscfg_rtspserver_baseport_max	mscfg_maxnum_port
		
//作为RTSP客户端，使用的RTP端口范围[40000,(mscfg_rtspserver_baseport-1)]
#define mscfg_rtspclient_baseport		40000
#define mscfg_rtspclient_baseport_max	(mscfg_rtspserver_baseport-1)

#define ENABLE_IPV6  ms_true
#define MSPTC_VERSION_HTTP			MSPTC_VERSION_HTTP_11
#define MSPTC_VERSION_RTSP			MSPTC_VERSION_RTSP_10

#define mscfg_maxlen_url		1024	//来自外部的URL地址
#define mscfg_maxlen_url2		512		//可预计长度的URL地址

#define mscfg_maxlen_send		32768
#define mscfg_maxlen_recv		32768	//65536
#define mscfg_maxlen_rtp		2000

#define mscfg_max_whitelist		4
#define mscfg_max_blacklist		4

#define MSPTC_DATE_FORMAT	"Date: %s GMT\r\n"

/*******************************************
封装格式
*******************************************/
#define FFMPEG_FORMAT_HLS		"hls"//"hls,applehttp"
/*******************************************
协议允许的请求方法
*******************************************/
#define METHOD_ALLOWED_HTTP "GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS"
#define METHOD_ALLOWED_RTSP "OPTIONS|DESCRIBE|ANNOUNCE|SETUP|PAUSE|PLAY|RECORD|GET_PARAMETER|TEARDOWN"
/*******************************************
跨域头信息
*******************************************/
#define MSPTC_ACCESS_CONTROL \
		"Access-Control-Allow-Origin: *\r\n" \
		"Access-Control-Allow-Headers: X-Requested-With\r\n" \
		"Access-Control-Allow-Methods: GET,POST,OPTIONS\r\n"

/*******************************************
SDP信息
*******************************************/		
#define msinfo_sdp \
		"v=0\r\n" \
		"o=- 1464329709034587 1 IN IP4 127.0.0.1\r\n" \
		"s=MPEG Transport Stream, streamed by msavskit(Email:msavskit@163.com)\r\n" \
		"m=video 0 RTP/AVP 33\r\n" \
		"c=IN IP4 0.0.0.0\r\n" \
		"a=control:trackid1\r\n"

#define OPTVAL_BOOL(optname,optval,default_val) \
	if(default_val==optval){ \
		optval=default_val; \
	}else{ \
		ms_verbose("%s:set value to %d",optname,optval); \
	}
	
#define OPTVAL_INIT(optname,optval,unvalid_val,default_val) \
	if(unvalid_val==optval){ \
		ms_verbose("%s:unset value,set to default %d",optname,default_val); \
		optval=default_val; \
	}else{ \
		ms_verbose("%s:set value to %d",optname,optval); \
	}
#define OPTVAL_INIT_DEFAULT(optname,optval,default_val) \
	ms_verbose("%s:unset value,set to default %d",optname,default_val); \
	optval=default_val; 
	
#define OPTVAL_INIT_VAILD(optname,optval,valid_val,default_val) \
	if(valid_val!=optval){ \
		ms_verbose("%s:unvalue,set to default %d",optname,default_val); \
		optval=default_val; \
	}else{ \
		ms_verbose("%s:set value to %d",optname,optval); \
	}


//msptc_file must be first
typedef enum ENUPROTOCOLIndex{
	msptc_file=0x00,
	msptc_udplite,	
	msptc_udp,
	msptc_tcp,
	msptc_rtp,
	msptc_msoshls,
	msptc_hls,
	msptc_https,
	msptc_dash,
	msptc_http_vod,
	msptc_http,
	msptc_rtsp,
	msptc_rtmps,
	msptc_rtmpte,
	msptc_rtmpe,
	msptc_rtmpt,
	msptc_rtmp,
	msptc_srt,
	msptc_ws,
	msptc_raw,
	msptc_none,
	msptc_pipe,
	msptc_fifo,
	msptc_msav,
	msptc_unknow
}ENUPROTOCOLIndex;
#define msstring_protocol \
	"file", \
	"udplite", \
	"udp", \
	"tcp", \
	"rtp", \
	"msoshls", \
	"hls", \
	"https", \
	"http", \
	"http", \
	"http", \
	"rtsp", \
	"rtmps", \
	"rtmpte",\
	"rtmpe",\
	"rtmpt",\
	"rtmp", \
	"srt",\
	"ws", \
	"raw", \
	"none", \
	"pipe", \
	"fifo", \
	"msav", \
	"unkonw" 

#define msptc_getPtcNameDes(ptcindex)	&msptcNameDes_list[ptcindex]

typedef enum IPPINGState{	
	ipping_state_unreachable=0x00,
	ipping_state_reachable,
	ipping_state_nocheck,
}IPPINGState;

typedef enum RTSPLowerTransport {
    RTSP_LOWER_TRANSPORT_UNKNOW = 0,  			/**< UDP/unicast */
    RTSP_LOWER_TRANSPORT_UDP ,  			/**< UDP/unicast */
    RTSP_LOWER_TRANSPORT_TCP ,   			/**< TCP; interleaved in RTSP */
    RTSP_LOWER_TRANSPORT_UDP_MULTICAST, 	/**< UDP/multicast */
    RTSP_LOWER_TRANSPORT_NB,
    RTSP_LOWER_TRANSPORT_HTTP ,  			/**< HTTP tunneled - not a proper transport mode as such,only for use via AVOptions */ 
    RTSP_LOWER_TRANSPORT_CUSTOM ,       		/**< Custom IO - not a public option for lower_transport_mask,but set in the SDP demuxer based on a flag.*/
}RTSPLowerTransport;

typedef enum RTSPDATAType {
	RTSP_DATATYPE_ERR_UNKNOW		=(-0x8000),
	RTSP_DATATYPE_ERR_IFRAME_RTP	=(-0x0007),
	RTSP_DATATYPE_ERR_CMD			=(-0x0006),
	RTSP_DATATYPE_ERR_NOMAGICNUM	=(-0x0005),
	RTSP_DATATYPE_ERR_CHANNLE		=(-0x0004),
	RTSP_DATATYPE_ERR_DATALEN		=(-0x0003),
	RTSP_DATATYPE_ERR_FIFOLEN_TOOSMALL=(-0x0002),
	RTSP_DATATYPE_ERR_FIFOLEN		=(-0x0001),
	RTSP_DATATYPE_RTP					=0x0000,
	RTSP_DATATYPE_RTCP				=0x0001,
	RTSP_DATATYPE_ERR_OK				=0x8000,
}RTSPDATAType;
typedef enum INTERFACEINType{
	INTERFACE_INTYPE_UNKNOW	=0x00,			//未指定输入/输出网卡
	INTERFACE_INTYPE_GLOBAL,				//通过XML配置的全局输入/输出网卡
	INTERFACE_INTYPE_USER,					//指令指定的输入/输出网卡
	INTERFACE_INTYPE_USER_PPPOE,			//指令指定的PPPOE输入网卡
	INTERFACE_INTYPE_USER_LINKDOWN,			//指令指定的输入/输出网卡，网卡未正常运行
	INTERFACE_INTYPE_USER_NOPPPOE			//指令指定的PPPOE输入网卡，拨号异常
}INTERFACEINType;

typedef enum RTPPAYLOADType {
	RTP_PAYLOADTYPE_AUDIO_PCMU			=0, 	//AV_CODEC_ID_PCM_MULAW, 8000, 1
	RTP_PAYLOADTYPE_AUDIO_GSM			=3, 	//AV_CODEC_ID_NONE, 8000, 1
	RTP_PAYLOADTYPE_AUDIO_G723			=4, 	//AV_CODEC_ID_G723_1
	RTP_PAYLOADTYPE_AUDIO_DVI4			=5, 	//AV_CODEC_ID_NONE, 8000, 1
	RTP_PAYLOADTYPE_AUDIO_DVI4_16000=6,	 		//AV_CODEC_ID_NONE, 16000, 1
	RTP_PAYLOADTYPE_AUDIO_LPC			=7, 	//AV_CODEC_ID_NONE, 8000, 1
	RTP_PAYLOADTYPE_AUDIO_PCMA			=8, 	//AV_CODEC_ID_PCM_ALAW, 8000, 1
	RTP_PAYLOADTYPE_AUDIO_G722			=9, 	//AV_CODEC_ID_ADPCM_G722, 8000, 1
	RTP_PAYLOADTYPE_AUDIO_L16			=10, 	//AV_CODEC_ID_PCM_S16BE, 44100, 2
	RTP_PAYLOADTYPE_AUDIO_L16_1			=11, 	//AV_CODEC_ID_PCM_S16BE, 44100, 1
	RTP_PAYLOADTYPE_AUDIO_QCELP			=12, 	//AV_CODEC_ID_QCELP, 8000, 1
	RTP_PAYLOADTYPE_AUDIO_CN			=13, 	//AV_CODEC_ID_NONE, 8000, 1
	RTP_PAYLOADTYPE_AUDIO_MPA			=14, 	//AV_CODEC_ID_MP2|AV_CODEC_ID_MP3,-1, -1
	RTP_PAYLOADTYPE_AUDIO_G728			=15, 	//AV_CODEC_ID_NONE, 8000, 1},
	RTP_PAYLOADTYPE_AUDIO_DVI4_11025=16,	 	//AV_CODEC_ID_NONE, 11025, 1},
	RTP_PAYLOADTYPE_AUDIO_DVI4_22050=17, 		//AV_CODEC_ID_NONE, 22050, 1},
	RTP_PAYLOADTYPE_AUDIO_G729			=18, 	//AV_CODEC_ID_NONE, 8000, 1},
	RTP_PAYLOADTYPE_VIDEO_CelB			=25, 	//AV_CODEC_ID_NONE, 90000, -1},
	RTP_PAYLOADTYPE_VIDEO_JPEG			=26, 	//AV_CODEC_ID_MJPEG, 90000, -1},
	RTP_PAYLOADTYPE_VIDEO_nv			=28, 	//AV_CODEC_ID_NONE, 90000, -1},
	RTP_PAYLOADTYPE_VIDEO_H261			=31, 	//AV_CODEC_ID_H261, 90000, -1},
	RTP_PAYLOADTYPE_VIDEO_MPV			=32, 	//AV_CODEC_ID_MPEG1VIDEO|AV_CODEC_ID_MPEG2VIDEO, 90000, -1},
	RTP_PAYLOADTYPE_DATA_MP2T			=33, 	//AV_CODEC_ID_MPEG2TS, 90000, -1},
	RTP_PAYLOADTYPE_VIDEO_H263			=34, 	//AV_CODEC_ID_H263, 90000, -1},
	RTP_PAYLOADTYPE_CUSTOM				=96,
	RTP_PAYLOADTYPE_UNKNOW				=-1,	//AV_CODEC_ID_H263, 90000, -1},
}RTPPAYLOADType;
typedef struct PTCNAMEDESContext{
    ms_string name;
	ms_string des;
}PTCNAMEDESContext;												
typedef struct RTPPAYLOADTYPEContext{
    RTPPAYLOADType pt;
    const char enc_name[16];
    const char codec_type[32];
    int clock_rate;
    int audio_channels;
}RTPPAYLOADTYPEContext;

typedef struct{
	ms_bool flag_init;
	ms_bool flag_dgwChange;	//默认网关发生变化
	ms_bool flag_pppoe;
	ms_u08 ipIn[128];		
	ms_u08 ipOut[128];			
	ms_u08 ifcIn[32];			
	ms_u08 ifcOut[32];	
	ms_u08 *ppp_ipIn;	
	ms_u08 *ppp_vtIfcIn;	//虚拟网卡，如ppp0,ppp1			
	ms_u08 *ppp_pyIfcIn;	//物理网卡，如eth0,eth1
	INTERFACEINType devType_in;			
	INTERFACEINType devType_out;	
}IFCInfo;

 typedef struct URLInfo{
 	ms_s08 ptcName[32];
	ms_s08 hostname[256];
	ms_s08 authorization[64];
	ms_s08 path[mscfg_maxlen_url];  
	ms_s32 port;
	ms_bool flag_ipv6;
	ms_bool flag_useipv6;
} URLInfo;

 typedef struct FILEOpt{
	ms_s08 newname[128];	
}FILEOpt;

typedef struct IFRAMEContext{
	ms_u08 magic;
	ms_u08 channel;
	ms_u32 len;
}IFRAMEContext;

typedef struct RTPHEADERContext{
	ms_bool flag_init;
	ms_bool flag_rtp;
	ms_u08 cc;
	ms_u08 x;
	ms_u08 p;
	ms_u08 v;
	ms_u08 pt;
	ms_u08 m;
	ms_u16 sequence_num;
	ms_u32 timestamp_base;
	ms_u32 timestamp;
	ms_u32 ssrc;
	//ms_u32 csrc[512];
//extern		
	ms_u16 profile_data;
	ms_u16 lenHeader_extension;
	//ms_u32 header_extension[512];

	ms_u32 lenHeader;
}RTPHEADERContext;
//RTSP(Over Tcp)-ROT的头部
typedef struct ROTHEADERContext{
	IFRAMEContext ifCtt;
	RTPHEADERContext rhCtt;
	ms_s32 payload_len;
}ROTHEADERContext;
typedef struct RTPPKTFIFOContext{
	ms_bool flag_use;
	ms_u16 sequence_num;	
	ms_u32 data_len;
	ms_byte data[1500];	
}RTPPKTFIFOContext;
#define MAXNUM_FIFO_RTPPKT	20
typedef struct RTPContext{
	IFRAMEContext iframe_ctt;
	RTPHEADERContext rh_ctt;
	//sequencenum check uses	
	ms_u16 snum_pre;
	ms_u16 snum_except;
	ms_bool flag_checkSNum;
	RTPPKTFIFOContext *pFifoPkt_ctt;
	ms_u16 fifoPtk_num;
}RTPContext;

 typedef struct UDPOpt{
	ms_string ipIn;
	ms_string ipOut;
	ms_string ifcIn;		
	ms_string ifcOut;
	ms_string ppp_pyIfcIn;	
	
	ms_string client_hostname;
	ms_bool enable_rpfilter;
	ms_u08 num_include_sources;
	ms_u08 num_exclude_sources;
	ms_u08 include_sources[mscfg_max_whitelist][128];
	ms_u08 exclude_sources[mscfg_max_whitelist][128];
//预制的OPT	
	ms_s32 client_prot;
	ms_s32 block;
	ms_s32 rw_timeout;	
	ms_s32 reuse_socket;		//must be int type
	ms_s32 fifo_size;
} UDPOpt;

typedef struct TCPOpt{
	ms_s32 flag_scanport;
	ms_s32 block;				
	ms_s32 listen;	
	ms_s32 open_timeout; 
	ms_s32 rw_timeout; 		
	ms_s32 recv_buffer_size;	
	ms_s32 send_buffer_size;	
	ms_s32 nodelay;			
	//listen ==1 ,uses
	ms_s32 reuse;
	ms_s32 backlog;
	ms_bool flag_noprint;
} TCPOpt;
typedef struct TSSLOpt{
	ms_s32 block;				
	ms_s32 listen;	
	ms_s32 open_timeout; 
	ms_s32 rw_timeout; 		
	ms_s32 recv_buffer_size;	
	ms_s32 send_buffer_size;	
	ms_s32 nodelay;			
	//listen ==1 ,uses
	ms_s32 reuse;
	ms_s32 backlog;
	ms_s32 fd_tcp;	
} TSSLOpt;
typedef struct SRTSERVERContext{	
	#define CONFIG_MAX_SRTCLIENT	8
	MSTHREADContext mstd_accecpt;
	ms_bool flag_stopAccecpt;
	ms_u64 timebase;	//定时检测客户端请求的时间基数
	ms_s32 clientNum;	//客户端总数
	ms_s32 clientFd[CONFIG_MAX_SRTCLIENT];		//存放客户端列表的块
	ms_bool flag_used[CONFIG_MAX_SRTCLIENT];	//标记块是否被使用	
}SRTSERVERContext;
typedef struct SRTOpt{	
	ms_s32 block;	
	ms_s32 listen;		
	ms_s32 rw_timeout; 		
	ms_s32 recv_buffer_size;	
	ms_s32 send_buffer_size;		
//listen ==1 ,uses
	ms_s32 peer_port;
	ms_s32 reuse;
	ms_s32 backlog;
	// res
	ms_s32 open_timeout;	
	//read
	ms_s08 clientip[128];
	SRTSERVERContext srtServer_ctt;
} SRTOpt;

typedef struct HTTPOpt{
	ms_s32 listen;
	ms_u08 range_type;
	ms_u32 range_byte;
	ms_u08 accept_type;
	ms_u08 connect_type;
	ms_s32 rw_timeout; 	
	ms_byte user_agent[128];
	ms_byte context_type[128];	//application/json
	ms_byte context[1024];

	ms_bool flag_302return;
	ms_bool flag_chunked;
	ms_bool flag_noprint;
} HTTPOpt;
// websocket根据data[0]判别数据包类型
// 比如0x81 = 0x80 | 0x1 为一个txt类型数据包
typedef enum{
    WDT_NULL 		= (-0x01), // 非标准数据包
    WDT_MINDATA		=0x00,  // 0x0：中间数据包
    WDT_TXTDATA		=0x01,  // 0x1：txt类型数据包
    WDT_BINDATA		=0x02,  // 0x2：bin类型数据包
    WDT_DISCONN		=0x08,  // 0x8：断开连接类型数据包 收到后需手动 close(fd)
    WDT_PING		=0x09, 	// 0x9：ping类型数据包 ws_api_recv 函数内自动回复pong
    WDT_PONG		=0x0A, 	// 0xA：pong类型数据包
} WSDataType;
typedef struct WSOpt{
	ms_s32 listen;
	ms_s32 rw_timeout; 
	WSDataType dataType;
	ms_bool flag_mask;
} WSOpt;

typedef struct {
  #if defined(OS_ANDROID)||defined(OS_WIN32) ||defined(OS_PLATFORM_ARM64)
  	ms_s32 len;
  #else
	socklen_t len;
 #endif
	struct sockaddr_in sockaddrs;
 	struct sockaddr_in6 sockaddrs6;
	ms_u08 has_info;
}CLIENTInfo;

typedef struct MSAVOpt{
	ms_u32 fifo_size;
} MSAVOpt;

typedef struct RTSPTRANSPORTInfo{
	ms_s08 source[80]; 
	ms_s32 ssrc;
	ms_s32 serverport_rtp;
	ms_s32 serverport_rtcp;
}RTSPTRANSPORTInfo;
typedef struct RTSPOpt{
	ms_u08 lower_transport;	
	ms_u08 transport;
	ms_pvoid url_rtspctt;
	ms_pvoid url_rtpctt;
	ms_pvoid url_rtcpctt;	
	ms_pvoid tcp_func;	
	ms_pvoid udp_func;	
	ms_pvoid rtp_func;
	ms_u32 rtp_port;
	ms_bool is_connected;
	THREADstate thread_started;	//0-unknow;1-start;2-stop
	MSLOCKContext mslock_ctt;
	RTSPTRANSPORTInfo transport_info;
	ms_bool is_rtpconnected;	
	ms_bool is_mpegts;		//
	ms_bool flag_authorization;		//

//user_io	
	ms_u08 timesec_beatheart;
/* BEGIN: Added by sugao<sugao_cn@163.com>, 2019/11/11   PN:001,Server   ANNOUNCE used */
	ms_s08 announce_url[mscfg_maxlen_url];
/* END:   Added by sugao<sugao_cn@163.com>, 2019/11/11 */

	MSTHREADContext msthread_ctt_heart;
	ms_bool cmd_stopheart;
}RTSPOpt;
typedef struct RTPOpt{
	ms_u08 payload_ype;	
	ms_bool isrtp;
	ms_bool is_offset;
	//test use,20210802
	ms_bool flag_rtpovertcp;
}RTPOpt;
typedef struct HLSOpt{
	ms_s08 vodpath[128];	
	ms_u32 list_size;
	ms_float time;
}HLSOpt;

typedef struct URLContext{
	ms_s32 fd;
	ms_s32 flags;
	ms_bool is_connected;
//使用原有连接来请求新的应用，好处在于避免了TCP新建连接带来的耗时。当前主要用于HLS的分片和M3U8文件请求
	ms_bool is_newRequesetKeepConnection;
	ms_bool is_cmdstop;		//HLS使用
	ms_bool is_rtspstream;	//RTSP和RTP使用 
	ms_pvoid priv_data;
	ms_pvoid priv_data2;	//RTP使用 
	ms_string ifcIn;
	ms_string ifcOut;
	union{
		FILEOpt	file;
		UDPOpt	udp;
		TCPOpt 	tcp;
		SRTOpt 	srt;
		WSOpt 	ws;
		RTPOpt 	rtp;
		HLSOpt 	hls;
		TSSLOpt 	tssl;
		HTTPOpt 	http;	
		MSAVOpt 	msav;
		RTSPOpt 	rtsp;
	}opt;
	ms_s08 url[mscfg_maxlen_url];
	ms_bool flag_location;	
	ms_s08 location[mscfg_maxlen_url];	
	URLInfo url_info;//set by call 
	CLIENTInfo peer_info;
	ms_bool flag_urlChange;	
} URLContext;

typedef enum {
	STREAM_UNKNOW	=0x00,
	STREAM_LIVE	,
	STREAM_FILE_VOD	,
	STREAM_LIVE_VOD	,
}STREAMType;

typedef struct {
	ms_s64 (*url_seek)( URLContext *, ms_s64, ms_s32);	
	ms_s32 (*url_check)(URLContext *, ms_s32);
	ms_s32 (*url_remove)(URLContext *);
	ms_s32 (*url_rename)(URLContext *);	
	ms_s32 (*url_empty)(URLContext *);
}PRIVEFile;
typedef struct {
	ms_s32 (*accept)(URLContext *);
	ms_s32 (*get_listen_handle)(URLContext *);
	ms_s32 (*shutdown)(URLContext *);
	ms_s32 (*get_window_size)(URLContext *);
}PRIVETcp;
typedef struct {
	ms_s32 (*accept)(URLContext *);
	ms_s32 (*get_listen_handle)(URLContext *);
}PRIVETssl;
typedef struct {
	ms_s32 (*accept)(URLContext *);
	ms_s32 (*get_listen_handle)(URLContext *);
}PRIVESrt;
typedef struct {
	ms_s32 (*accept)(URLContext *s);
	ms_s32 (*get_listen_handle)(URLContext *);
}PRIVEHttp;
typedef struct {
	ms_s32 (*play)(URLContext *);
	ms_s32 (*pause)(URLContext *);
	ms_s32 (*seek)(URLContext *,int64_t );
}PRIVERtsp;

typedef struct {
	ms_u32 (*playlist_totalnum)(URLContext *s);
	ms_u32 (*list_size)(URLContext *s);
	ms_u32 (*m3u8_parase)(URLContext *s);
}PRIVEHls;

typedef struct URLProtocol{
	PTCNAMEDESContext *nameDes;
	ms_s32 (*url_open)(URLContext *);
	ms_s32 (*url_read)(URLContext *, ms_pu08 , ms_s32 );
	ms_s32 (*url_write)(URLContext *,ms_pu08 , ms_s32 );
	ms_s32 (*url_close)(URLContext *);
	ms_string (*url_info)(URLContext *);
	union{
		PRIVEFile 	file;
		PRIVETcp 	tcp;
		PRIVETssl 	tssl;
		PRIVESrt 	srt;
		PRIVEHttp 	http;
		PRIVERtsp 	rtsp;
		PRIVEHls 	hls;
	}priv_func;
	ms_s32 flags;
	struct URLProtocol *next;
}URLProtocol;
typedef struct M3U8Context {
	ms_u08 resolution[64];	
	ms_u32 bandwidth;	
	ms_u08 url[256];	
} M3U8Context;

typedef enum{
	content_type_unknow=0x00,
	content_type_mpegurl,
	content_type_mp2t,
}ENUM_CONTENTType;
typedef struct HTTPContext {
	URLContext tcpctt;
	ms_pbyte replyfiledata;
	ms_s32 replyfiledata_len;
	URLProtocol *tcp_ptl;
	
	ms_u08 method[32];
	ms_s32 status_code;
	ms_u08 des[128];	
	ms_u32 content_len;
	ENUM_CONTENTType content_type;	// 0-unknow,1-x-mpegurl,2-mp2t
} HTTPContext;

typedef struct URLVal{
	URLContext url_ctt;
	URLProtocol *purl_ptl;
	ENUPROTOCOLIndex ptl_index;
	ms_s64 base_sys;
	//mpegts use
	ms_s64 Etimep_pat_pmt;
	ms_s64 Etimep_pat_pmt_update;
}URLVal;

typedef struct WEBHOSTInfo{
	unsigned char server_host[256];
	unsigned char server_ip[256];
	unsigned char server_port[256];
	ms_bool flag_ipv6;
	ms_byte url_param[512];
}WEBHOSTInfo;
typedef struct RTSPREQUESTData{
	unsigned char CSeq[128];
	unsigned char Transport[128];
	unsigned char Range[128];	
	unsigned char Session[128];
	unsigned char pscAccept[128];
}RTSPREQUESTData;
typedef struct HTTPREQUESTData{
	WEBHOSTInfo webhost_info;
}HTTPREQUESTData;

typedef struct WEBREQUESTContext{
	ENUPROTOCOLIndex ptl_index;
	ms_byte method[32];
	ms_byte url[512];
	ms_byte protocol[32];
	ms_byte user_agent[512];
	ms_byte xReal_ip[128];
	ms_bool falg_hascontent;
	ms_byte content_type[256];
	ms_byte content[5120];
	ms_byte connection[mscfg_maxlen_recv+1];
	ms_u32  content_len;
//webSocket
	ms_byte sec_webSocket_key[256];		//Sec-WebSocket-Key
	ms_byte sec_webSocket_version[64];	//Sec-WebSocket-Version
	ms_byte sec_webSocket_accept[256];	//Sec-WebSocket-Accept
	union{
		HTTPREQUESTData http_rd;
		RTSPREQUESTData rtsp_rd;
	}extern_data;
}WEBREQUESTContext;

typedef enum NETSTATE_CODE {
//1xx:Notification - Request received, proceed	
	NETSTATE_CODE_CONTINUE             				=100,
//2XX: Success - the operation was successfully received, understood, and accepted		
	NETSTATE_CODE_OK                  	 				=200,
	NETSTATE_CODE_CREATED              				=201,
	NETSTATE_CODE_LOW_ON_STORAGE_SPACE 	=250,
//3XX: Redirection - Further action must be taken to complete the request.	
	NETSTATE_CODE_MULTIPLE_CHOICES     			=300,
	NETSTATE_CODE_MOVED_PERMANENTLY    		=301,
	NETSTATE_CODE_MOVED_TEMPORARILY    		=302,
	NETSTATE_CODE_SEE_OTHER            				=303,
	NETSTATE_CODE_NOT_MODIFIED         			=304,
	NETSTATE_CODE_USE_PROXY            				=305,
//4XX: Client error - request has syntax error or cannot be implemented
	NETSTATE_CODE_BAD_REQUEST          			=400,
	NETSTATE_CODE_UNAUTHORIZED         			=401,
	NETSTATE_CODE_PAYMENT_REQUIRED   		=402,
	NETSTATE_CODE_FORBIDDEN            				=403,
	NETSTATE_CODE_NOT_FOUND            				=404,
	NETSTATE_CODE_METHOD               				=405,
	NETSTATE_CODE_NOT_ACCEPTABLE       			=406,
	NETSTATE_CODE_PROXY_AUTH_REQUIRED  		=407,
	NETSTATE_CODE_REQ_TIME_OUT         			=408,
	NETSTATE_CODE_GONE                 					=410,
	NETSTATE_CODE_LENGTH_REQUIRED      			=411,
	NETSTATE_CODE_PRECONDITION_FAILED  		=412,
	NETSTATE_CODE_REQ_ENTITY_2LARGE    		=413,
	NETSTATE_CODE_REQ_URI_2LARGE       			=414,
	NETSTATE_CODE_UNSUPPORTED_MTYPE    		=415,
	NETSTATE_CODE_ERRORIO    					=420,
	NETSTATE_CODE_ERROR_CONTENT			=421,
	NETSTATE_CODE_PARAM_NOT_UNDERSTOOD 	=451,
	NETSTATE_CODE_CONFERENCE_NOT_FOUND 	=452,
	NETSTATE_CODE_BANDWIDTH            			=453,
	NETSTATE_CODE_SESSION              				=454,
	NETSTATE_CODE_STATE                				=455,
	NETSTATE_CODE_INVALID_HEADER_FIELD 		=456,
	NETSTATE_CODE_INVALID_RANGE        			=457,
	NETSTATE_CODE_RONLY_PARAMETER      		=458,
	NETSTATE_CODE_AGGREGATE            				=459,
	NETSTATE_CODE_ONLY_AGGREGATE       			=460,
	NETSTATE_CODE_TRANSPORT            				=461,
	NETSTATE_CODE_UNREACHABLE          			=462,
//5XX: Server side error - the server was unable to fulfill a valid request	
	NETSTATE_CODE_INTERNAL             				=500,
	NETSTATE_CODE_NOT_IMPLEMENTED     	 		=501,
	NETSTATE_CODE_BAD_GATEWAY          			=502,
	NETSTATE_CODE_SERVICE             	 			=503,
	NETSTATE_CODE_GATEWAY_TIME_OUT			=504,
	NETSTATE_CODE_VERSION              				=505,
	NETSTATE_CODE_UNSUPPORTED_OPTION   		=551,
	NETSTATE_CODE_MAX   						=600,
}ENUM_NETSTATE_CODE;

#ifndef MSPROTOCOL_C
extern PTCNAMEDESContext msptcNameDes_list[];
//rtp(tcp)  interleaverframe
extern ms_void 
	msptc_api_rtpIframeDebug(IFRAMEContext *prtspif_ctt,ms_bool enable_debug);
extern RTSPDATAType 
	msptc_api_rtpIframeDrop(MSBFIFOSIZEContext  *plist_stream_fifoctt,ms_pbyte recvbuf,int *plen);
extern ms_s32 
	msptc_api_rtpIframeSet(ms_u08 *buf,ms_s32 len,ms_bool is_offset);
extern RTSPDATAType  
	msptc_api_rtpIframeGet(IFRAMEContext *prtspif_ctt,ms_u08 *buf,ms_s32 len);
extern RTSPDATAType 
	msptc_api_isRtspCmd(ms_pbyte recvbuf,int len);
extern ms_bool 
	msptc_api_isRtspTeardown(ms_pbyte recvbuf,int len);
extern ms_void 
	msptc_api_rtpHeaderDebug(RTPHEADERContext *prh_ctt,ms_bool enable_debug);
extern ms_bool
	msptc_api_rtpHeaderGet(RTPHEADERContext *prh_ctt,ms_u08 *buf,ms_s32 len,ms_bool debug);
extern ms_s32  
	msptc_api_rtpHeaderSet(RTPHEADERContext ms_in *prh_ctt,ms_u08 payload,ms_s08 ms_out *buf ,ms_s32 ms_out size,ms_bool is_offset);
extern ms_void 
	msptc_api_rtpHeaderDebug2(RTPContext * prtp_ctt,ms_string desinfo,ms_u08 *buf,ms_s32 len,ms_bool enable_debug);
extern ms_bool 
	msptc_api_rtpHeader_checkSequence(RTPContext * prtp_ctt,ms_string desinfo,ms_u08 *buf,ms_s32 len);
extern ms_void 
	msptc_api_rtpHeaderDebug3(ms_u08 *buf,ms_s32 len,ms_bool enable_debug);
extern ms_bool 
	msptc_api_rtpCheck(RTPHEADERContext *prh_ctt,ms_u08 *buf, int len ,ms_bool flag_checkiframe);
extern ms_s32 
	msptc_api_rtpFifoout(RTPContext * prtp_ctt,ms_u08 **ppbuf, int *len );
extern void 
	msptc_api_rtpDec(RTPContext * prtp_ctt,ms_u08 *buf, int *len ,ms_bool flag_checkiframe);
extern ms_u32 
	msptc_api_getContextLen(char *inbuf,ms_u32 len);
extern ms_s08 
	msptc_api_init(ms_void);
extern ms_void 
	msptc_api_deinit(ms_void);
extern ms_void 
	msptc_api_register(ms_void);
extern void * 
	msptc_api_matchByName(const ms_s08 *name);
extern void * 
	msptc_api_matchByPtcindex(ENUPROTOCOLIndex ptcindex);
extern URLProtocol * 
	msptc_api_matchByUrl(const ms_s08 *url);
extern URLProtocol * 
	msptc_api_matchAndGetUrlinfo_byUrl(const ms_u08 *url,URLInfo *purl_info);
extern ENUPROTOCOLIndex 
	msptc_api_getPtcindex(char *url,char *format,ms_bool isvod);
extern ms_string 
	msptc_api_getPtcName(ENUPROTOCOLIndex ptcindex);
extern ms_s32 
	msptc_api_io(URLContext *pcilent_ctt, ms_pu08 buf, ms_s32 len,ms_s32 (*url_io)(URLContext *, ms_pu08 , ms_s32 ));
extern ms_bool 
	msptc_api_statusCode_isLocation(ms_s32 statuscode);
extern ms_bool 
	msptc_api_statusCode_isOK(ms_s32 statuscode);
extern ms_void 
	msptc_api_replay(ms_string protocol,char *outbuf,ms_u32 statuscode,ms_string exinfo,ms_bool flag_token);
extern ms_void 
	msptc_api_replayOk(ms_string protocol,char *outbuf,ms_bool flag_token);
extern ms_void 
	msptc_api_replayContent(ms_string protocol,char *content,char *content_string,char *outbuf);
extern ms_void  
	msptc_api_replayMovedTemporarily(WEBREQUESTContext * prequest_ctt,ms_string location_url,char *outbuf);
extern ms_void  
	msptc_api_replayBusy(char *outbuf,int cur_connect,int max_connect);
extern ms_void  
	msptc_api_printStatusCode(int statuscode);
extern ms_s64 
	msptc_api_getVodSize(ms_string ms_in url);
extern void 
	msptc_api_urlSplit_urlinfo(URLInfo *purl_info,ms_string url);
extern void 
	msptc_api_urlSplit_urlctt(URLContext *s);
extern ms_bool 
	msptc_api_parseRequest(char *inbuf,WEBREQUESTContext *prequest_ctt,ms_string str_parase_out);
extern ms_string 
	msptc_api_getName(ms_u08 ptcindex);
extern ms_bool 
	msptc_api_parseSdp(ms_string sdpfile);
extern ms_bool 
	msptc_api_checkUrl(ms_cstring ms_in url);
extern ms_bool 
	msptc_api_isUrl(ms_cstring ms_in url);
extern RTPPAYLOADTYPEContext *
	msptc_api_getRtpPTInfo(RTPPAYLOADType pt);
extern ms_void 
	msptc_api_info(ms_string ms_out pbuf);
extern ms_string 
	msptc_api_version(ms_void);

extern ms_s32 
	ws_api_replyClient(ms_s32 fd, ms_byte* psecWebSocketKey);
extern ms_s32 
	ws_api_send(ms_s32 fd, ms_byte *buf, ms_s32 len,ms_bool flag_mask,WSDataType dataType);
extern ms_s32 
	ws_api_recv(ms_s32 fd, void* buf, ms_s32 len, WSDataType* pdataType);
extern ms_void 
	file_api_record(ms_s08 index,ms_byte *buf, ms_s32 size);
extern ms_void 
	file_api_enRecord(ms_bool flag_enable,ms_s08 index,ms_byte *buf, ms_s32 size);

extern const char * const netStateCode_string[]; 
#ifdef CONFIG_MSPROTOCOL_SRT
extern ms_void 
	mssrt_bstatsGL(int fd ,ms_bool flag_sender);
extern ms_void 
	mssrt_bstatsInstant(int fd ,ms_bool flag_sender);
#endif

#else
void 
	msptc_api_urlSplit_urlinfo(URLInfo *purl_info,ms_string url);
ms_bool 
	msptc_api_rtpHeaderGet(RTPHEADERContext *prh_ctt,ms_u08 *buf,ms_s32 len,ms_bool debug);
ms_string 
	msptc_api_getPtcName(ENUPROTOCOLIndex ptcindex);
#endif

#define msprotocol_api_replay_exinfo( protocol,outbuf,statuscode, tbuf,fmt, arg...) \
	ms_sprintfs(tbuf, fmt,##arg); \
	msptc_api_replay(protocol, outbuf, statuscode,tbuf,ms_true);
#define msprotocol_api_replay_desinfo( protocol,outbuf,statuscode, tbuf,fmt, arg...) \
	msprotocol_api_replay_exinfo(protocol, outbuf, statuscode, tbuf, "Desinfo:" fmt "\r\n", ##arg);

#ifdef __cplusplus
}
#endif
#endif

